home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / µSim 1.0.5 / source / ControlStore.c < prev    next >
Encoding:
Text File  |  1995-12-06  |  12.7 KB  |  490 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993,1994,1995 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11. //#pragma load "MacDump"
  12. #ifndef __MOREFILESEXTRAS__
  13. #include    <MoreFilesExtras.h>
  14. #endif
  15.  
  16. #include    "UtilsSys7.h"
  17. #include    "FabLibResIDs.h"
  18.  
  19. #include    "Globals.h"
  20. #include    "Animation.h"
  21. #include    "ControlStore.h"
  22. #include    "DoMenu.h"
  23. #include    "Microprogram_Ed.h"
  24. #include    "SimUtils.h"
  25.  
  26. #if defined(FabSystem7orlater)
  27.  
  28. #pragma segment Rare
  29.  
  30. const short controlStoreObject[] = {kP_CONTSTORE, 0 };
  31.  
  32. short    myFileRefN;
  33. Boolean    DocIsOpen;
  34.  
  35. static FSSpec    workingFile;
  36. static ScriptCode    wkFileScript;
  37. static Boolean    dirtyCSFlag = false;
  38.  
  39. /*====== internal routines ======*/
  40. static OSErr gotSave(Handle buf);
  41. static OSErr gotSaveAs(Handle buf, OSType);
  42. static OSErr SafeSave(Handle wrBuf, FSSpec *onWhichFile, ScriptCode);
  43.  
  44. /* RevertFile: we revert to the last saved version of the doc */
  45.  
  46. OSErr RevertFile(void)
  47. {
  48. FSSpec    tempNewFile = workingFile;
  49.  
  50. FSClose(myFileRefN);
  51. myFileRefN = 0;
  52. DocumentIsDirty(false);
  53. return myOpenCSFile(&tempNewFile, wkFileScript, false);
  54. }
  55.  
  56. /* myOpenCSFile: we read all that stuff (the microprogram) from the file */
  57.  
  58. OSErr myOpenCSFile(FSSpec *theFile, ScriptCode theScript, Boolean StationeryDoc)
  59. {
  60. Str255    tempS;
  61. ParamBlockRec    myPB;
  62. EventRecord    dummyEv;
  63. Rect    tempRect;
  64. GrafPtr    savePort;
  65. register Handle    tempBuffer;
  66. unsigned long    fileSize;
  67. short    length;
  68. register OSErr    err;
  69. register Boolean    isLocked = false;
  70.  
  71. SetCursor(*gWatchHandle);
  72. GetPort(&savePort);
  73. SetPort(gWPtr_Microprogram_Ed);
  74. if ((err = FSpOpenDFCompat(theFile, StationeryDoc ? fsRdPerm : fsRdWrPerm, &myFileRefN)) == permErr) {
  75.     err = FSpOpenDFCompat(theFile, fsRdPerm, &myFileRefN);
  76.     isLocked = true;
  77.     }
  78. if (err == noErr) {
  79.     if ((err = GetEOF(myFileRefN, (long *)&fileSize)) == noErr) {
  80.         if ((tempBuffer = NewHandleGeneral(fileSize)) != 0L) {
  81.             myPB.ioParam.ioCompletion = 0L;
  82.             myPB.ioParam.ioRefNum = myFileRefN;
  83.             HLock(tempBuffer);
  84.             myPB.ioParam.ioBuffer = *tempBuffer;
  85.             myPB.ioParam.ioReqCount = fileSize;
  86.             myPB.ioParam.ioPosMode = fsFromStart;
  87.             myPB.ioParam.ioPosOffset = 0L;
  88.             (void)PBReadAsync(&myPB);
  89.             while (myPB.ioParam.ioResult > 0) {
  90.                 SystemTask();
  91.                 (void)EventAvail(everyEvent, &dummyEv);
  92.                 }
  93.             HUnlock(tempBuffer);
  94.             if ((err = myPB.ioParam.ioResult) == noErr) {
  95.                 Point    tempCell;
  96.                 register unsigned char *spanningPtr;
  97.                 register short    i;
  98.  
  99.                 LSetDrawingMode(false, Lists[kL_COMMENTS]);
  100.                 DoNew();
  101.                 BlockMoveData(*tempBuffer, gCsMemory, kSIZE_CSMEM + kSIZE_ASSMEM);
  102.                 tempCell.h = 0;
  103.                 HLock(tempBuffer);
  104.                 for (spanningPtr = (unsigned char *)*tempBuffer + kSIZE_CSMEM + kSIZE_ASSMEM,
  105.                     i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  106.  
  107.                     tempCell.v = i;
  108.                     LSetCell(spanningPtr + 1, *spanningPtr, tempCell, Lists[kL_COMMENTS]);
  109.                     spanningPtr += *spanningPtr + 1;
  110.                     }
  111.                 HUnlock(tempBuffer);
  112.                 LSetDrawingMode(true, Lists[kL_COMMENTS]);
  113.                 if (StationeryDoc == false) {
  114.                     workingFile = *theFile;
  115.                     wkFileScript = theScript;
  116.                     SetWTitle(gWPtr_Microprogram_Ed, theFile->name);
  117.                     }
  118.                 DocumentIsDirty(false);
  119.             /* get cell contents and put into TextEdit field */
  120.                 length = 255;    /* maximum length of text */
  121.                 tempCell.h = 0;
  122.                 tempCell.v = theSelection[kL_COMMENTS];
  123.                 LGetCell(&tempS, &length, tempCell, Lists[kL_COMMENTS]);
  124.                 TESetText(&tempS, length, TEs[kKEY_COMMENT]);
  125.                 RefreshTE(kKEY_COMMENT);
  126.         //        UnloadSeg(RefreshTE);
  127.                 SetMir((*(gCsMemory + theSelection[kL_COMMENTS])).cstore);
  128.                 tempRect = *keyrects[kKEY_LIST];
  129.                 tempRect.right -= kScrollbarAdjust;
  130.                 InvalRect(&tempRect);
  131.                 DoMenuWindows(kMItem_Microprogram);
  132.                 }
  133.             DisposeHandle(tempBuffer);
  134.             }
  135.         else err = MemError();
  136.         }
  137.     if (err || StationeryDoc || isLocked)
  138.         (void)FSClose(myFileRefN);
  139.     }
  140. if (err || StationeryDoc || isLocked)
  141.     myFileRefN = 0;
  142. SetPort(savePort);
  143. InitCursor();
  144. return err;
  145. }
  146.  
  147. /* mySaveCSFile: the user has chosen Save or Save As… from the menus */
  148.  
  149. OSErr mySaveCSFile(int selector)
  150. {
  151. Point    tempCell;
  152. register Handle    readyBuffer;
  153. register OSErr    err;
  154.  
  155. SetCursor(*gWatchHandle);
  156. tempCell.h = 0;
  157. tempCell.v = theSelection[kL_COMMENTS];
  158. ChangedListSelection(tempCell, kL_COMMENTS, false);
  159. if (readyBuffer = PrepareBufferFromList()) {
  160.     switch (selector) {
  161.         case kGOT_SAVE: err = gotSave(readyBuffer);
  162.             break;
  163.         case kGOT_SAVEAS: err = gotSaveAs(readyBuffer, kFTY_CSTORE);
  164.             break;
  165.         case kGOT_SAVESTATIONERY: err = gotSaveAs(readyBuffer, kFTY_CSTOREPAD);
  166.             break;
  167.         }
  168.     DisposeHandle(readyBuffer);
  169.     }
  170. else err = MemError();
  171. InitCursor();
  172. return err;
  173. }
  174.  
  175. /* gotSave: the user has told us to Save. Is he working at a previously saved
  176. document or not? */
  177.  
  178. static OSErr gotSave(Handle buf)
  179. {
  180. register OSErr    err;
  181.  
  182. if (myFileRefN != 0)
  183.     err = SafeSave(buf, &workingFile, wkFileScript);
  184. else
  185.     err = gotSaveAs(buf, kFTY_CSTORE);
  186. return err;
  187. }
  188.  
  189. /* gotSaveAs: we must definitely show up the dialog box for "save-a-file"
  190. and save it if asked for */
  191.  
  192. static OSErr gotSaveAs(Handle buf, OSType theType)
  193. {
  194. enum {
  195. kSTR_CSPROMPT = 135,
  196. kSTR_CSDEFNAME
  197. };
  198.  
  199. StandardFileReply    mySFR;
  200. FInfo    fndrInfo;
  201. register Handle    sH1;
  202. register Handle    sH2;
  203. short    tmpFRefN;
  204. register SignedByte    state1, state2;
  205. register OSErr    err;
  206.  
  207. state1 = WantThisHandleSafe(sH1 = (Handle)GetString(kSTR_CSPROMPT));
  208. state2 = WantThisHandleSafe(sH2 = (Handle)GetString(kSTR_CSDEFNAME));
  209. InitCursor();
  210. StandardPutFile((ConstStr255Param)*sH1, (ConstStr255Param)*sH2, &mySFR);
  211. SetCursor(*gWatchHandle);
  212. if (mySFR.sfGood) {
  213.     if (mySFR.sfReplacing) {
  214.         if (noErr == (err = FSpGetFInfoCompat(&mySFR.sfFile, &fndrInfo))) {
  215.             if (fndrInfo.fdType == theType)
  216.                 err = SafeSave(buf, &mySFR.sfFile, mySFR.sfScript);
  217.             else
  218.                 (void)StopAlert_UPP(kALRT_WRONGEXISTINGDOC, myStdFilterProcNoCancel);
  219.             }
  220.         }
  221. /* not replacing an existing file */
  222.     else if ((err = FSpCreateCompat(&mySFR.sfFile, kFCR_MINE, theType, mySFR.sfScript)) == noErr)
  223.         if ((err = FSpOpenDFCompat(&mySFR.sfFile, fsRdWrPerm, &tmpFRefN)) == noErr)
  224.             if ((err = WriteMicroprogramData(buf, &mySFR.sfFile, theType, tmpFRefN, mySFR.sfScript)) == noErr) {
  225.                 if (theType == kFTY_CSTORE) {
  226.                     if (myFileRefN)    /* close old working file if any */
  227.                         (void)FSClose(myFileRefN);
  228.                     myFileRefN = tmpFRefN;    /* this is the new work file */
  229.                     workingFile = mySFR.sfFile;
  230.                     wkFileScript = mySFR.sfScript;
  231.                     SetWTitle(gWPtr_Microprogram_Ed, mySFR.sfFile.name);
  232.                     DocumentIsDirty(false);
  233.                     }
  234.                 else if (theType == kFTY_CSTOREPAD) {
  235.                     (void) FSpSetIsStationery(&mySFR.sfFile);
  236.                     (void)FSClose(tmpFRefN);
  237.                     }
  238.                 }
  239.             else {    /* error writing data */
  240.                 (void)FSClose(tmpFRefN);
  241.                 (void)FSpDeleteCompat(&mySFR.sfFile);
  242.                 }
  243.     }
  244. else err = 1;
  245. HSetState(sH1, state1);
  246. HSetState(sH2, state2);
  247. return(err);
  248. }
  249.  
  250. /* SafeSave: we should do a safe save of the document
  251. (a previously saved version already exists) */
  252.  
  253. OSErr SafeSave(Handle buf, FSSpec *onWhichFile, ScriptCode myFScript)
  254. {
  255. Str255    tempFName;
  256. FSSpec    thisFSSpec;
  257. long    thisDirID;
  258. short    thisVRefNum, newFileRefn;
  259. register OSErr    err;
  260.  
  261. if (0)    /* test if file locked (FSpExchange does not) */
  262.     err = fLckdErr;
  263. else {
  264.     MyNumToString(TickCount(), tempFName);
  265.     if ((err = FindFolder(onWhichFile->vRefNum, kTemporaryFolderType, kCreateFolder,
  266.                     &thisVRefNum, &thisDirID)) == noErr) {
  267.         (void)FSMakeFSSpecCompat(thisVRefNum, thisDirID, (ConstStr255Param)&tempFName, &thisFSSpec);
  268.         if ((err = FSpCreateCompat(&thisFSSpec, kFCR_MINE, kFTY_CSTORE,
  269.                             myFScript)) == noErr)
  270.             if ((err = FSpOpenDFCompat(&thisFSSpec, fsRdWrPerm, &newFileRefn)) == noErr)
  271.                 if ((err = WriteMicroprogramData(buf, &thisFSSpec, kFTY_CSTORE, newFileRefn, myFScript)) == noErr) {
  272.                     if ((err = FSpExchangeFilesCompat(&thisFSSpec, onWhichFile)) == noErr) {
  273.                         if (myFileRefN)
  274.                             (void)FSClose(myFileRefN);
  275.                         myFileRefN = newFileRefn;
  276.                         workingFile = *onWhichFile;
  277.                         wkFileScript = myFScript;
  278.                         SetWTitle(gWPtr_Microprogram_Ed, onWhichFile->name);
  279.                         DocumentIsDirty(false);
  280.                         err = FSpDeleteCompat(&thisFSSpec);
  281.                         }
  282.                     }
  283.                 else {
  284.                     (void)FSClose(newFileRefn);
  285.                     (void)FSpDeleteCompat(&thisFSSpec);    // the temporary one
  286.                     if (err == dskFulErr) {
  287.                         (void)StopAlert_UPP(kALRT_NOSAVE, myStdFilterProcNoCancel);
  288.                         err = 1;
  289.                         }
  290.                     }
  291.         }
  292.     }
  293. return(err);
  294. }
  295.  
  296. /* WriteMicroprogramData: writes physically the data into the file */
  297.  
  298. OSErr WriteMicroprogramData(Handle prepBuffer, FSSpec *theFSpec, OSType theType, short theOpenedFile,
  299.                         ScriptCode theFileSc)
  300. {
  301. ParamBlockRec    myPB;
  302. EventRecord    dummyEv;
  303. register OSErr    err;
  304.  
  305. myPB.ioParam.ioCompletion = 0L;
  306. myPB.ioParam.ioBuffer = (Ptr)gCsMemory;
  307. myPB.ioParam.ioReqCount = kSIZE_CSMEM + kSIZE_ASSMEM;
  308. myPB.ioParam.ioPosMode = fsFromStart;
  309. myPB.ioParam.ioRefNum = theOpenedFile;
  310. myPB.ioParam.ioPosOffset = 0L;
  311. (void)PBWriteAsync(&myPB);
  312. while (myPB.ioParam.ioResult > 0) {
  313.     SystemTask();
  314.     (void)EventAvail(everyEvent, &dummyEv);
  315.     }
  316. if ((err = myPB.ioParam.ioResult) == noErr) {
  317.     myPB.ioParam.ioBuffer = *prepBuffer;
  318.     myPB.ioParam.ioReqCount = InlineGetHandleSize(prepBuffer);
  319.     myPB.ioParam.ioPosMode = fsAtMark;
  320.     myPB.ioParam.ioRefNum = theOpenedFile;
  321.     myPB.ioParam.ioPosOffset = 0L;
  322.     HLock(prepBuffer);
  323.     (void)PBWriteAsync(&myPB);
  324.     while (myPB.ioParam.ioResult > 0) {
  325.         SystemTask();
  326.         (void)EventAvail(everyEvent, &dummyEv);
  327.         }
  328.     HUnlock(prepBuffer);
  329.     if ((err = myPB.ioParam.ioResult) == noErr)
  330.         err = AddSTRRes2Doc(theFSpec, kFCR_MINE, theType, kSTR_ApplicationName, theFileSc);
  331.     }
  332. return err;
  333. }
  334.  
  335. /* DoNew: starts afresh with a new microprogram */
  336.  
  337. void DoNew(void)
  338. {
  339. enum {
  340. kSTR_UNTITLED = 137
  341. };
  342.  
  343. register StringHandle    UntitledStr;
  344. register SignedByte    oldstate;
  345.  
  346. ResetMicroprogramWindow();
  347. DocIsOpen = true;
  348. ActivateObjs(controlStoreObject);
  349. if (UntitledStr = GetString(kSTR_UNTITLED)) {
  350.     oldstate = WantThisHandleSafe((Handle)UntitledStr);
  351.     SetWTitle(gWPtr_Microprogram_Ed, *UntitledStr);
  352.     (void) PLstrcpy(workingFile.name, *UntitledStr);
  353.     HSetState((Handle)UntitledStr, oldstate);
  354.     }
  355. }
  356.  
  357. /* ResetMicroprogramWindow: wipes out the window to an empty one */
  358.  
  359. void ResetMicroprogramWindow(void)
  360. {
  361. Str255    tempS;
  362. register Point tempCell = { 0, 0};
  363. short    leng;
  364. register short    i;
  365.  
  366. for ( i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  367.     tempCell.v = i;
  368.     LClrCell(tempCell, Lists[kL_COMMENTS]);
  369.     }
  370. tempCell.v = 0;
  371. leng = 255;
  372. LGetCell(&tempS, &leng, tempCell, Lists[kL_COMMENTS]);
  373. TESetText(&tempS, leng, TEs[kKEY_COMMENT]);
  374. keyDownDest = kKEY_BRTO;
  375.  
  376.     {
  377.     register union u_mir tempmir;
  378.  
  379.     tempmir.cstore = 0L;
  380.     tempmir.bits.c = 15;
  381.     tempmir.bits.dsc = 1;
  382.     SetControlsFromMir(tempmir);
  383. //    UnloadSeg(SetControlsFromMir);
  384.     }
  385. }
  386.  
  387. /* PrepareBufferFromList: sets up a buffer containing all the info
  388. about the microprogram, so that it is ready to be saved into a file. */
  389.  
  390. Handle PrepareBufferFromList(void)
  391. {
  392. Str255    tempS;
  393. Point    tempCell;
  394. register Handle    myH = nil;
  395. short    len;
  396. register OSErr    err;
  397. register short i;
  398.  
  399. if (Lists[kL_COMMENTS] && gCsMemory)
  400.     if (myH = NewHandleGeneral(0L)) {
  401.         tempCell.h = 0;
  402.         for (i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  403.             tempCell.v = i;
  404.             len = 255;
  405.             LGetCell(&tempS[1], &len, tempCell, Lists[kL_COMMENTS]);
  406.             tempS[0] = len;
  407.             if (err = PtrAndHand(&tempS, myH, len + 1))
  408.                 break;
  409.             }
  410.         if (err) {
  411.             DisposeHandle(myH);
  412.             myH = nil;
  413.             }
  414.         }
  415. return myH;
  416. }
  417.  
  418. #pragma segment Main
  419.  
  420. /* ReadyToTerminate: we decide if we are ready to quit gracefully;
  421. shall we save an unsaved document? Let the user choose… */
  422.  
  423. Boolean ReadyToTerminate(void)
  424. {
  425. enum {
  426. kPUSH_SAVE = 1,
  427. kPUSH_CANCEL,
  428. kPUSH_DONTSAVE
  429. };
  430.  
  431. register OSErr    err;
  432.  
  433. if (gRstatus) {
  434.     if (CautionAlert_UPP(kALRT_CPURUNNING, myStdFilterProc) == cancel)
  435.         return false;
  436.     }
  437. if (dirtyCSFlag) {
  438.     ParamText(workingFile.name, nil, nil, nil);
  439.     switch (CautionAlert_UPP(kALRT_SAVE, myStdFilterProc)) {
  440.         case kPUSH_SAVE:
  441.             err = mySaveCSFile(kGOT_SAVE);
  442.             UnloadSeg(mySaveCSFile);
  443.             if (err) {
  444.                 if (err != 1)
  445.                     ErrorAlert(err);
  446.                 return false;
  447.                 }
  448.             break;
  449.         case kPUSH_CANCEL:
  450.             return false;
  451.             break;
  452.         case kPUSH_DONTSAVE:
  453.             break;
  454.         }
  455.     }
  456. if (myFileRefN) {
  457.     FSClose(myFileRefN);
  458.     myFileRefN = 0;
  459.     }
  460. DocumentIsDirty(false);
  461. DocIsOpen = false;
  462. DeactivateObjs(controlStoreObject);
  463. MyZeroBuffer((long *)gCsMemory, numOfLongs(kSIZE_ASSMEM + kSIZE_CSMEM));
  464. CloseMicroProg(gWPtr_Microprogram_Ed);
  465. SetMir(0L);
  466. return true;
  467. }
  468.  
  469. /* DocumentIsDirty: we are told if the document has been modified
  470. since last save. */
  471.  
  472. void DocumentIsDirty(Boolean dirtiness)
  473. {
  474. if (dirtyCSFlag != dirtiness) {
  475.     if (dirtyCSFlag = dirtiness) {
  476.         EnableItem(gMenu_File, kMItem_Save_Control_St);
  477.         }
  478.     else {
  479.         DisableItem(gMenu_File, kMItem_Save_Control_St);
  480.         }
  481.     if (myFileRefN && dirtyCSFlag)
  482.         EnableItem(gMenu_File, kMItem_Revert_to_Saved);
  483.     else
  484.         DisableItem(gMenu_File, kMItem_Revert_to_Saved);
  485.     }
  486. }
  487.  
  488. #endif
  489.  
  490.